// crc16
/**
计算modbus的crc16校验码的小工具
***/
package main

import (
	"encoding/hex"
	"fmt"
	"os"
)

func main() {
	str := ""
	for i, v := range os.Args {
		if i > 0 {
			str += v
		}
	}
	fmt.Printf("src:\t%s\n", str)
	src, e := hex.DecodeString(str)
	if e != nil {
		fmt.Println(e)
		os.Exit(1)
	}
	crc := Crc16_rtu_A001(src)
	fmt.Printf("crc16:\t0x%04x\n", crc)
	fmt.Printf("crc16:\t%04xH\n", crc)
	lb := byte(crc)
	hb := byte(crc >> 8)
	fmt.Printf("modbus:\t%s %02x%02x\n", hex.EncodeToString(src), lb, hb)
}

func Crc16_rtu_A001(dat []byte) uint16 {
	var crc_reg, crc_gen uint32
	crc_reg, crc_gen = 0xFFFF, 0xA001

	for i, l := 0, len(dat); i < l; i++ {
		crc_reg = (uint32(dat[i]) & 0xff) ^ crc_reg
		for j := 8; j > 0; j-- {
			if crc_reg&0x01 == 1 {
				crc_reg >>= 1
				crc_reg ^= crc_gen
			} else {
				crc_reg >>= 1
			}
		}
	}
	return uint16(crc_reg)
}
